package gimys;


import org.newdawn.slick.*;
import org.newdawn.slick.geom.*;

public class Animal extends SolidObject {

	public enum AnimalState { FOLLOW_PATH, ATTACK_ENNEMY, TRACK_PLAYER, FOLLOW_FRIEND, FLEE_PLAYER, EATING }
	public enum Agressivity { NEUTRAL, LITTLE_AGRESSIVE, VERY_AGRESSIVE }

	private Path path;
	private AnimalState state;
	private int stateTime;
	protected Skin skin;

	private float radiusDetection;
	private float radiusAttack;
	private int attackTimer;
	private SolidObject target;
	public boolean hasMoved = false;

	private int seductionEventTimer;
	private SpriteSheet loveSprite;

	public Animal(Point pLocation, Skin pSkin, Path pPath) throws SlickException {
		super();
		this.deltaYSprite = -16;
		if (pSkin != Skin.PRINCE) {
			this.sprite = new SpriteSheet("data/Mechant"+pSkin.ordinal()+".png", 16, 32);
			this.loveSprite = new SpriteSheet("data/Mechant"+pSkin.ordinal()+"a.png", 16, 32);
		}
		this.collisionShape = new Circle(pLocation.x+8, pLocation.y+8, 8);
		this.radiusDetection = 80;
		this.radiusAttack = this.radiusDetection/2;

		this.path = pPath;
		this.state = AnimalState.FOLLOW_PATH;
		this.type = Type.ANIMAL;
		this.skin = pSkin;
		this.speed = 0.07f;
		this.attackTimer = 0;
		this.seductionEventTimer = 0;
	}

	public Animal( Skin pSkin, Path pPath) throws SlickException {
		this( pPath.getPoint(), pSkin, pPath);

	}

	/***** EVENTS *****/

	/**
	 * Called at every tick time
	 */
	public void update(int delta) {
		//System.out.println("updating");
		this.count++;
		this.stateTime += delta;
		this.attackTimer += delta;
		this.seductionEventTimer += delta;
	}

	/**
	 * Called when break heart is clicked on this animal
	 */
	public boolean breakHeartEventHandler(Player player) {
		if (this.seductionEventTimer > 3000) {
			System.out.println("Attempting to break heart");
			// Try to use the seduction during an attack
			if (this.skin != player.getSkin()) {
				if (player.useSeductionLevel(25)) {
					this.target = null;
					this.resetAttackTimer();
					this.seductionEventTimer = 0;
					System.out.println("alt");
					return true;
				}
				// Not enough seduction power
				else {
					return false;
				}
			}
			// Same skin, not attacking
			else {
				return true;
			}
		}
		else {
			return false;
		}
	}

	/**
	 * Called when get seduced is clicked on this animal
	 */
	public boolean getSeducedEventHandler(Player player) {
		if (this.seductionEventTimer > 3000) {
			// Try to copy the skin
			System.out.println("Attempt to get Seduced");
			if (this.skin != player.getSkin()) {
				if (player.useSeductionLevel(25)) {
					player.addSkin(this.skin);
					this.seductionEventTimer = 0;
					this.setTarget(null);
					System.out.println("ctrl");
					return true;
				}
				// Not enough seduction power
				else {
					return false;
				}
			}
			// Same skin, not copying
			else {
				return false;
			}
		}
		else {
			return false;
		}	
	}

	/***** GETTER AND SETTERS *****/

	public Skin getSkin() {
		return this.skin;
	}

	public float getRadiusDetection() {
		return this.radiusDetection;
	}

	public float getRadiusAttack() {
		return this.radiusAttack;
	}

	public Image getImage() {
		//if (this.target != null) System.out.println(this.target);
		
		if (this.target != null && this.target.getSkin() == this.skin) {
			if (hasMoved) {
				return this.loveSprite.getSubImage((this.count /200) % 2, this.direction.ordinal() + 2);
			} else {
				switch(this.direction) {
				case TOP:
					return this.loveSprite.getSubImage(0, 1);
				case BOTTOM:
					return this.loveSprite.getSubImage(1, 1);
				case RIGHT:
					return this.loveSprite.getSubImage(1, 0);
				case LEFT:
					return this.loveSprite.getSubImage(0, 0);
				}
			}
		}
		else {
			if (hasMoved) {
				return this.sprite.getSubImage((this.count /200) % 2, this.direction.ordinal() + 2);
			} else {
				switch(this.direction) {
				case TOP:
					return this.sprite.getSubImage(0, 1);
				case BOTTOM:
					return this.sprite.getSubImage(1, 1);
				case RIGHT:
					return this.sprite.getSubImage(1, 0);
				case LEFT:
					return this.sprite.getSubImage(0, 0);
				}
			}
		}
		return null;
	}

	public String toString() {
		String s = this.skin.toString();
		return s;
	}

	public AnimalState getState() {
		return this.state;
	}

	public void setState(AnimalState pState) {
		this.state = pState;
	}

	public int getAttackTimer() {
		return this.attackTimer;
	}

	public Path getPath() {
		return this.path;
	}

	public SolidObject getTarget() {
		return this.target;
	}

	public void setTarget(SolidObject pTarget) {
		this.target = pTarget;
	}

	public void resetAttackTimer() {
		this.attackTimer = 0;
	}

	public Agressivity getAgressivityToward(Skin pSkin) {
		switch (this.skin) {
		case DONKEY:
			if (pSkin == Skin.MONKEY) return Agressivity.LITTLE_AGRESSIVE;
			else if (pSkin == Skin.SNAKE) return Agressivity.VERY_AGRESSIVE;
			else if (pSkin == Skin.WOLF) return Agressivity.NEUTRAL;
			else return Agressivity.NEUTRAL;
		case MONKEY:
			if (pSkin == Skin.DONKEY) return Agressivity.LITTLE_AGRESSIVE;
			else if (pSkin == Skin.SNAKE) return Agressivity.NEUTRAL;
			else if (pSkin == Skin.WOLF) return Agressivity.VERY_AGRESSIVE;
			else return Agressivity.NEUTRAL;
		case SNAKE:
			if (pSkin == Skin.DONKEY) return Agressivity.VERY_AGRESSIVE;
			else if (pSkin == Skin.MONKEY) return Agressivity.NEUTRAL;
			else if (pSkin == Skin.WOLF) return Agressivity.LITTLE_AGRESSIVE;
			else return Agressivity.NEUTRAL;
		case WOLF:
			if (pSkin == Skin.DONKEY) return Agressivity.NEUTRAL;
			else if (pSkin == Skin.MONKEY) return Agressivity.VERY_AGRESSIVE;
			else if (pSkin == Skin.SNAKE) return Agressivity.LITTLE_AGRESSIVE;
			else return Agressivity.NEUTRAL;
		default: return Agressivity.NEUTRAL;
		}
	}	
}
